﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using DotNetUI.Controls;

using OpenCvSharp.Internal;

using Xc.DataAccess.CodeReader;
using Xc.DataAccess.CodeReader.Models;
using Xc.DataAccess.CodeReader.Models.Filters;

namespace Xc.Logics.CodeReaders.Views
{
    /// <summary>
    /// MainView.xaml 的交互逻辑
    /// </summary>
    public partial class MainView : UserControl
    {
        private readonly IOpenCvService cameraService;

        public MainView(IOpenCvService cameraService)
        {
            InitializeComponent();
            this.cameraService = cameraService;
            Loaded += MainView_Loaded;
        }

        private void MainView_Loaded(object sender, RoutedEventArgs e)
        {
            ViewModel.FilerSources = cameraService.FilterInfos;
            Button_Click(sender, e);
        }
        private void LBoxSort_OnPreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                var pos = e.GetPosition(LBoxSort);
                HitTestResult result = VisualTreeHelper.HitTest(LBoxSort, pos);
                if (result == null)
                {
                    return;
                }
                var listBoxItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
                if (listBoxItem == null || listBoxItem.Content != LBoxSort.SelectedItem)
                {
                    return;
                }
                DataObject dataObj = new DataObject(listBoxItem.Content as FilterLayer);
                DragDrop.DoDragDrop(LBoxSort, dataObj, DragDropEffects.Move);
            }
        }

        private void LBoxSort_OnDrop(object sender, DragEventArgs e)
        {
            var pos = e.GetPosition(LBoxSort);
            var result = VisualTreeHelper.HitTest(LBoxSort, pos);
            if (result == null)
            {
                return;
            }
            //查找元数据
            var sourcePerson = e.Data.GetData(typeof(FilterLayer)) as FilterLayer;
            if (sourcePerson == null)
            {
                return;
            }
            //查找目标数据
            var listBoxItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit);
            if (listBoxItem == null)
            {
                return;
            }
            var targetPerson = listBoxItem.Content as FilterLayer;
            if (ReferenceEquals(targetPerson, sourcePerson))
            {
                return;
            }
            ((ObservableCollection<FilterLayer>)LBoxSort.ItemsSource).Remove(sourcePerson);
            ((ObservableCollection<FilterLayer>)LBoxSort.ItemsSource).Insert(LBoxSort.Items.IndexOf(targetPerson), sourcePerson);
        }
        internal class Utils
        {
            //根据子元素查找父元素
            public static T FindVisualParent<T>(DependencyObject obj) where T : class
            {
                while (obj != null)
                {
                    if (obj is T)
                        return obj as T;

                    obj = VisualTreeHelper.GetParent(obj);
                }
                return null;
            }
        }
        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            ViewModel.IsRunning = true;
            var res = await cameraService.OpenAsync(new CameraServiceOption { ServiceIndex = ViewModel.Index, FunctionName = "相机1" });
            if (res.IsSuccess)
            {
                _ = await Task.Factory.StartNew(async () =>
                   {
                       int index=ViewModel.Index;
                       while (true)
                       {

                           if (ViewModel.IsRunning)
                           {
                               try
                               {
                                   var result = await cameraService.ReadMat(ViewModel.Filters.Select(p => p.Filter).ToArray());
                                   if (result.IsSuccess)
                                   {
                                       Dispatcher.Invoke(() =>
                                       {
                                           var res = cameraService.ToImage(result.Data);
                                           if (res.IsSuccess)
                                           {
                                               _img.Source = res.Data;
                                           }
                                       });

                                   }
                               }
                               catch (Exception)
                               {

                               }
                           }


                           await Task.Delay(100);
                           if (index != ViewModel.Index)
                           {
                               ViewModel.IsRunning = false;
                               cameraService.Close();
                               Button_Click(sender,e);
                               break;
                           }
                       }
                   });

            }
            else
            {
                MessageBox.Show(res.Message);
            }
        }
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {

        }

        private void btn_Click(object sender, RoutedEventArgs e)
        {
            if (sender is DotNetButton btn && btn.DataContext is FilterDetailInfo info)
            {
                if (info.FilterType == null)
                {
                    return;
                }
                var obj = (FilterBase)Activator.CreateInstance(info.FilterType);
                if (obj == null)
                {
                    return;
                }
                var properties = obj.GetType().GetProperties();
                foreach (var property in properties)
                {
                    var c = (InputParameterAttribute)Attribute.GetCustomAttribute(property, typeof(InputParameterAttribute));
                    if (c != null)
                    {
                        var value = property.GetValue(obj);
                        if (value == default && !property.PropertyType.IsGenericType&&property.PropertyType!=typeof(string))
                        {
                            property.SetValue(obj, Activator.CreateInstance(property.PropertyType));
                        }
                    }
                }
                this.ViewModel.Filters.Add(new FilterLayer(info, obj));
            }
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            if (sender is DotNetButton button && button.DataContext is FilterLayer layer)
            {
                this.ViewModel.Filters.Remove(layer);

            }
        }

        private void DotNetToggleButton_Checked(object sender, RoutedEventArgs e)
        {

        }

        private void DotNetToggleButton_Unchecked(object sender, RoutedEventArgs e)
        {

        }
    }
}
